﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using EnvDTE;

namespace CslaExtension.Wizard
{
    public partial class ModelChoser : Form
    {
        private DTE _dte;
        private SelectedItem _selectedItem;
        private Dictionary<string, ProjectItem> _allModels;
        public string ModelFile { get; private set; }
        string referencePath;

        public ModelChoser(DTE dte, SelectedItem item)
            : this()
        {
            _dte = dte;
            _selectedItem = item;
            _allModels = new Dictionary<string, ProjectItem>();
        }

        public ModelChoser()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            FillListBox();
            SetButtonEnabled();
        }

        private void SetButtonEnabled()
        {
            if (listBox1.SelectedIndex < 0)
            {
                button1.Enabled = false;
            }
            else
            {
                button1.Enabled = true;
            }
        }

        private void FillListBox()
        {
            Solution solution = _dte.Solution;

            //Project currentProject = _dte.ActiveDocument.ProjectItem.ContainingProject;
            //设置CslaExtension.tt文件被创建到的路径
            //如果当在项目中选中的子文件夹 is not null 的时候 那么会把CslaExtension.tt 创建到该文件夹下
            //否则创建到该项目的根下 
            //取当前选中项目的路径
            referencePath = string.Empty;
            if (_selectedItem != null)
            {
                if (_selectedItem.ProjectItem != null)
                    referencePath = Path.GetDirectoryName(_selectedItem.ProjectItem.FileNames[0]);
                else
                    referencePath = Path.GetDirectoryName(_selectedItem.Project.FullName);
            }

            //没有选中项目的话
            //就去当前vs中激活项目的路径
            //if (referencePath == string.Empty)
            //    referencePath = Path.GetDirectoryName(currentProject.FullName);

            //在当前项目递归找EDMX文件
            foreach (Project pro in solution.Projects)
            {
                foreach (ProjectItem pi in pro.ProjectItems)
                    Recurse(pi);
            }

            foreach (string pi in _allModels.Keys)
            {
                listBox1.Items.Add(pi);
            }

            if (listBox1.Items.Count > 0)
                listBox1.SelectedIndex = 0;
        }

        private void Recurse(ProjectItem item)
        {
            foreach (ProjectItem pi in item.ProjectItems)
                Recurse(pi);

            if (item.Name.ToUpper().EndsWith(".EDMX"))
                _allModels.Add(RelativePath(referencePath, item.FileNames[0]), item);
        }


        /// <summary>
        /// 将绝对路径转相对路径
        /// </summary>
        /// <param name="absolutePath">主路径</param>
        /// <param name="relativeTo">需要对比的路径</param>
        /// <returns>转换后的相对路径</returns>
        private string RelativePath(string absolutePath, string relativeTo)
        {
            //绝对路径以"\\"分割成数组
            string[] absoluteDirectories = absolutePath.Split('\\');
            //需要对比的路径以"\\"分割成数组
            string[] relativeDirectories = relativeTo.Split('\\');

            //取2者中较短的
            int length = absoluteDirectories.Length < relativeDirectories.Length ? absoluteDirectories.Length : relativeDirectories.Length;

            int lastCommonRoot = -1;
            int index;

            //先来查找共同的根
            //从前往后找 
            for (index = 0; index < length; index++)
            {
                if (absoluteDirectories[index] == relativeDirectories[index])
                    lastCommonRoot = index;
                else
                    break;
            }

            //没有找到相同的根
            if (lastCommonRoot == -1)
                throw new ArgumentException("Paths do not have a common base");

            //生成相对路径
            StringBuilder relativePath = new StringBuilder();

            //填充..\\
            for (index = lastCommonRoot + 1; index < absoluteDirectories.Length; index++)
                if (absoluteDirectories[index].Length > 0)
                    relativePath.Append("..\\");

            //填充文件夹
            for (index = lastCommonRoot + 1; index < relativeDirectories.Length - 1; index++)
                relativePath.Append(relativeDirectories[index] + "\\");
            relativePath.Append(relativeDirectories[relativeDirectories.Length - 1]);

            return relativePath.ToString();
        }

        private void listBox1_DoubleClick(object sender, EventArgs e)
        {
            if (listBox1.SelectedIndex < 0)
                return;

            ModelFile = listBox1.SelectedItem.ToString();
            DialogResult = System.Windows.Forms.DialogResult.OK;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ModelFile = listBox1.SelectedItem.ToString();
            DialogResult = System.Windows.Forms.DialogResult.OK;
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetButtonEnabled();
        }

    }

}
